import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;

@Slf4j
public class CodeCloneUtil {

    public static void clone(String path, String codeUrl, String branchName, boolean deleteXlsx, boolean deleteGit) throws Exception{
        String projectName = codeUrl.substring(codeUrl.lastIndexOf("/") + 1 ,codeUrl.length() - ".git".length());
        String dir = path.replaceAll("\\\\", "/");
        cloneCode(dir, codeUrl, projectName);

        if(deleteXlsx){
            //删除yfk-app\yfk-front\src\main\resources\template下的所有xlsx文件
            deleteXlsx(dir, projectName);
        }

        update(dir, projectName);
        Git git = openRpo(dir, projectName);
        checkoutBranch(dir, projectName, git, branchName);

        if(deleteGit){
            deleteGitFile(dir, projectName);
        }
    }

    private static void deleteGitFile(String dir, String projectName) {
        File file = new File(dir);
        if(!file.exists()){
            return;
        }

        String gitFileDirPath = dir.replaceAll("\\\\", "/");
        gitFileDirPath = gitFileDirPath.endsWith("/") ? gitFileDirPath : gitFileDirPath + "/";
        File gitFileDir = new File(gitFileDirPath + projectName + "/.git");

        FileUtil.del(gitFileDir);
    }


    public static void deleteXlsx(String dir, String projectName){
        File file = new File(dir);
        if(!file.exists()){
            return;
        }

        String xlsxFileDirPath = dir.replaceAll("\\\\", "/");
        xlsxFileDirPath = xlsxFileDirPath.endsWith("/") ? xlsxFileDirPath : xlsxFileDirPath + "/";
        File xlsxFileDir = new File(xlsxFileDirPath + projectName + "/yfk-front/src/main/resources/template");

        File[] files = xlsxFileDir.listFiles(e -> e.getName().endsWith(".xlsx"));
        if(ObjectUtils.isEmpty(files)){
            return;
        }
        for (File file1 : files) {
            FileUtil.del(file1);
        }
    }


    private static void update(String dir, String projectName) throws Exception{
        dir = dir.endsWith("/") ? dir + projectName : dir + "/" + projectName;
        File file = new File(dir);
        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec("git remote update origin --prune", new String[]{}, file);
        BufferedOutputStream outputStream = (BufferedOutputStream)process.getOutputStream();
        InputStream inputStream = process.getInputStream();
        InputStream errorStream = process.getErrorStream();
        process.waitFor(1, TimeUnit.MINUTES);
        log.info("git update inputStream:{}", IoUtil.read(inputStream));
        log.info("git update errorStream:{}", IoUtil.read(errorStream));
        process.destroy();
        process.destroyForcibly();
        IoUtil.close(errorStream);
        IoUtil.close(inputStream);
        IoUtil.close(outputStream);
    }

    private static void checkoutBranch(String dir, String projectName, Git git, String branchName) throws Exception{
        dir = dir.endsWith("/") ? dir + projectName : dir + "/" + projectName;
        File file = new File(dir);
        //当前分支名称是最新分支，拉取最新代码
        if(branchName.equals(git.getRepository().getBranch())){
            //先切换到master分支
            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec("git checkout master", new String[]{}, file);
            BufferedOutputStream outputStream = (BufferedOutputStream)process.getOutputStream();
            InputStream inputStream = process.getInputStream();
            InputStream errorStream = process.getErrorStream();
            process.waitFor(1, TimeUnit.MINUTES);
            log.info("切换到master分支 inputStream:{}", IoUtil.read(inputStream));
            process.destroy();
            process.destroyForcibly();

            IoUtil.close(errorStream);
            IoUtil.close(inputStream);
            IoUtil.close(outputStream);

            //删除本地分支
            runtime = Runtime.getRuntime();
            process = runtime.exec("git branch --delete " + branchName, new String[]{}, file);
            outputStream = (BufferedOutputStream)process.getOutputStream();
            inputStream = process.getInputStream();
            errorStream = process.getErrorStream();
            process.waitFor(1, TimeUnit.MINUTES);
            log.info("删除本地分支 inputStream:{}", IoUtil.read(inputStream));
            process.destroy();
            process.destroyForcibly();


            IoUtil.close(errorStream);
            IoUtil.close(inputStream);
            IoUtil.close(outputStream);

        }

        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec("git fetch", new String[]{}, file);
        BufferedOutputStream outputStream = (BufferedOutputStream)process.getOutputStream();
        InputStream inputStream = process.getInputStream();
        InputStream errorStream = process.getErrorStream();
        process.waitFor(1, TimeUnit.MINUTES);
        log.info("git fetch inputStream:{}", IoUtil.read(inputStream));
        log.info("git fetch errorStream:{}", IoUtil.read(errorStream));
        process.destroy();
        process.destroyForcibly();
        IoUtil.close(errorStream);
        IoUtil.close(inputStream);
        IoUtil.close(outputStream);
//        session.sendMessage(new TextMessage(JSONUtil.toJsonPrettyStr(Response.buildSuccessResponse("git fetch("+projectName+")\r\n" + IoUtil.readUtf8(errorStream)))));

        //拉取远程分支  git checkout -b update[新建分支名] origin/develop[远程分支名]
        runtime = Runtime.getRuntime();
        process = runtime.exec("git checkout -b "+branchName+" origin/" + branchName, new String[]{}, file);
        outputStream = (BufferedOutputStream)process.getOutputStream();
        inputStream = process.getInputStream();
        errorStream = process.getErrorStream();
        process.waitFor(1, TimeUnit.MINUTES);
        log.info("拉取远程分支到本地 inputStream:{}", IoUtil.read(inputStream));
        String msg = IoUtil.readUtf8(errorStream);
        process.destroy();
        process.destroyForcibly();


        IoUtil.close(errorStream);
        IoUtil.close(inputStream);
        IoUtil.close(outputStream);
    }

    private static void cloneCode(String dir, String codeUrl, String projectName) throws Exception {
        File file = new File(dir);
        if(!file.exists()){
            file.mkdirs();
        }
        if(file.listFiles(e -> e.isDirectory() && e.getName().equals(projectName)).length == 0){
            Runtime runtime = Runtime.getRuntime();

            Process process = runtime.exec("git clone " + codeUrl, new String[]{}, file);
            BufferedOutputStream outputStream = (BufferedOutputStream)process.getOutputStream();
            InputStream inputStream = process.getInputStream();
            InputStream errorStream = process.getErrorStream();
            process.waitFor(1, TimeUnit.MINUTES);
            IoUtil.readUtf8(inputStream);
            String msg = IoUtil.readUtf8(errorStream);
            log.info("拉取{}结果:{}", projectName, msg);


            process.destroy();
            process.destroyForcibly();
            IoUtil.close(errorStream);
            IoUtil.close(inputStream);
            IoUtil.close(outputStream);

//            log.info("代码clone inputStream:{}", IoUtil.read(inputStream));
//            log.info("代码clone errorStream:{}", IoUtil.read(errorStream));
        }else{
            log.info("{}不为空", dir + projectName);
        }
    }

    public static Git openRpo(String dir, String projectName) throws Exception{
        dir = dir.endsWith("/") ? dir + projectName : dir + "/" + projectName;
        Repository repository = new FileRepositoryBuilder()
                .setGitDir(Paths.get(dir, ".git").toFile())
                .build();
        Git git = new Git(repository);

        return git;
    }

    public static void forceMergeMaster(String stdTradePath) {
        try{
            Runtime runtime = Runtime.getRuntime();

            Process process = runtime.exec("git fetch origin master --force ", new String[]{}, new File(stdTradePath));
            BufferedOutputStream outputStream = (BufferedOutputStream)process.getOutputStream();
            InputStream inputStream = process.getInputStream();
            InputStream errorStream = process.getErrorStream();
            process.waitFor(1, TimeUnit.MINUTES);
            IoUtil.readUtf8(inputStream);
            String msg = IoUtil.readUtf8(errorStream);

            process.destroy();
            process.destroyForcibly();
            IoUtil.close(errorStream);
            IoUtil.close(inputStream);
            IoUtil.close(outputStream);





            process = runtime.exec("git reset --hard  origin/master", new String[]{}, new File(stdTradePath));
            outputStream = (BufferedOutputStream)process.getOutputStream();
            inputStream = process.getInputStream();
            errorStream = process.getErrorStream();
            process.waitFor(1, TimeUnit.MINUTES);
            IoUtil.readUtf8(inputStream);
            msg = IoUtil.readUtf8(errorStream);

            process.destroy();
            process.destroyForcibly();
            IoUtil.close(errorStream);
            IoUtil.close(inputStream);
            IoUtil.close(outputStream);
        }catch (Exception e){
            log.error("", e);
        }

    }

//    public static void main(String[] args) throws Exception{
//        clone("D:\\workspace\\新建文件夹\\a", "git@coding.jd.com:std-trade/std-trade-compare-merge.git", "test");
//    }
}
